跳到主要内容

模拟赛题解/2025.9.22 模拟赛

· 阅读需 10 分钟
Sintle
Developer

T1-题意(orchestra)

题面

给定一串长度为 nn 的数对序列 (xi,yi)(x_i,y_i),其中 xi,yix_i,y_i 都是整数。

mm 次询问,每次给定两个整数 a,ba,b,你需要先选定一个整数 kk(注意 kk 可以为 00),然后再选定一个正整数序列 1p1p2pkn1\leq p_1\leq p_2\leq\cdots\leq p_k\leq n(若 k=0k=0 则该序列为空),使得

min(a+i=1kxpi,b+i=1kypi)min\left(a+\sum_{i=1}^k x_{p_i},b+\sum_{i=1}^k y_{p_i}\right)

最大,输出这个最大值。

1n103,0xi105,0yi1012,1m2×105,1ai,bi10121\leq n\leq 10^3,0\leq\sum|x_i|\leq10^5,0\leq\sum|y_i|\leq10^{12},1\leq m\leq2\times10^5,1\leq|a_i|,|b_i|\leq10^{12}

题解

首先把 aa 提出来,发现此时 xx 部分固定了。

并且 xx 的值域只有区区 10510^5,于是我们考虑用类似于背包的方式,用 fif_i 表示 j=1kxpj=i\sum_{j=1}^k x_{p_j}=i 的时候 j=1kypj\sum_{j=1}^k y_{p_j} 的最大取值。

最小值最大容易想到二分答案,于是二分判定是否可行。

复杂度 O((n+m)logxi)O((n+m)\log\sum x_i)

T2-戏已完结(plaudite)

题面

给定两个正整数 n,mn,m,其中 nmn\leq m

我们称长度为 nn 的非负整数序列 a=(a1,a2,,an)a=(a_1,a_2,\cdots,a_n) 满足以下条件是良好序列

  • 0a1a2anm0\leq a_1\leq a_2\leq\cdots\leq a_n\leq m

对于一个良好序列 aa,定义函数 f(a)f(a),其生成的序列如下:

f(a)=sort(a11,a22,,ann)f(a)=sort(a_1-1,a_2-2,\cdots,a_n-n)

即将序列 (a11,a22,,ann)(a_1-1,a_2-2,\cdots,a_n-n) 进行升序排序后得到 f(a)f(a)

接下来有 qq 个询问,每个询问给定 kk,求:

  • 计算所有可能的良好序列 aa 对应的 f(a)f(a) 中第 kk 个元素的总和,并输出该值对 998244353998244353 取模后的结果。

tips:可能对解题有用的定理

在一个 n×nn\times n 的网格中,我们称 (i,j)(i+1,j)(i,j)\rightarrow (i+1,j) 这一步为一个横线,所有 (0,0)(n,n)(0,0)\rightarrow(n,n)(只能向上或者向右走)的路径中,设恰好有 kk 条横线在 y=xy=x 直线上方(即横线两端点均在直线上或上方)的路径有 ckc_k 个,那么所有 ckc_k 相等。

1knm105,1q1041\leq k\leq n\leq m\leq 10^5,1\leq q\leq10^4

题解

考虑转化成一个格路计数问题:

  • 有一个 n×mn \times m 的网格,每次可以往上或往右走,要从 (0,0)(0,0) 走到 (n,m)(n,m)
  • 每次从 (i,j)(i+1,j)(i,j) \to (i+1,j) 就确定了 ai+1=ja_{i+1} = j,称 (i,j)(i+1,j)(i,j) \to (i+1,j) 为斜线。
  • 对于某个 x+i(k1)x+i(k-1),可以转化到斜线:画出 y=x+k(nkm)y=x+k(-n \leq k \leq m) 的所有斜线,对于每条斜线,若有一个横线在它的上方经过,则将 ansnk+1ansmans_{n-k+1}\dots ans_m 加上 1。

考虑对于每条斜线贡献时,我们想要求对于每个 ii 计算,有多少个方案恰好有 cc 个横线在它的上方经过。

先将对路径斜线转化为路径斜线的情形,这部分贡献可以 O(n)O(n) 算出。

枚举某条斜线上的前两个位置,设这这是路径的第 cc 次、最后一次触碰斜线的位置。

我们有结论:

  • 在一个 n×mn \times m 的网格从 (0,0)(0,0) 走到 (n,n)(n,n),设所有 (i,j)(i+1,j)(i,j) \to (i+1,j) 在对角线上方经过的次数为 cc 的方案数是 anscans_c,则所有 cc 相等,均为 (nn+1)\binom{n}{n+1}

于是设定第一次、最后一次触碰斜线位置后,可贡献的 cc 是一个区间,因为区间中的每个 cc 贡献相等。

直接枚举答案复杂度是 O(n3)O(n^3),考虑如何优化。

x=kx=k 的直线分成 k[0,mn]k \in [0,m-n]k[(n1),1]k \in [-(n-1),-1] 两部分。[mn+1,m][m-n+1,m][(n1),1][-(n-1),-1] 是对称的。

考虑 k[(n1),1]k \in [-(n-1),-1] 的部分。

假设我们枚举了触碰起始点之间的长度 lenlen,则任意分数组上的修改位置是确定的。

枚举 lenlen,那么段触碰起始点之间的方案是固定的,前后两段的形式都是 (0,0)(a,b)(0,0) \to (a,b) 且不触碰 y=x+(b+1a)y=x+(b+1-a) 的折线计数(假设把后一段对称一下)。

把这两段拆开挂起来,就变成了一段折线,形式也是 (0,0)(a,b)(0,0) \to (a,b) 且不触碰 y=x+(b+1a)y=x+(b+1-a),且 (a,b)(a,b) 是很左很左的点。这部分的方案数就变成了两个组合数根据 lenlen 的形式。

再枚举所有的 kk 加起来,发现加和的式子能拆掉,可以 O(1)O(1) 计算同一个 lenlen 的方案数。于是这部分能做到 O(n)O(n)

考虑 k[0,mn]k \in [0,m-n] 的部分。

由于我们只需考虑分数组上修改权,所以可以只关心:对于所有触碰起点 kk 点,其方案数之和,起点和终点由 lenlen 决定,不再考虑起点。

由于起终点之间的方案数就是 (2lenlen)/(len+1)\binom{2len}{len}/(len+1) 的形式,我们代入这些部分全部在斜线上面走。那折线就变成了从 (0,0)(0,0) 到起点是走最短路径,走上去到 (n,m)(n,m) 并且不穿过斜线。

这样也是两段 (0,0)(a,b)(0,0)\to (a,b) 不触碰 y=x+(b+1a)y=x+(b+1-a) 的形式,可以把两段折线拼起来,贡献就是两个组合数相乘。

枚举所有的 kk 加起来,发现要求若干个如下的形式:

p=0mn(2p+kp)(n+m+k2pnp)\sum_{p=0}^{m-n} \binom{2p+k}{p} \binom{n+m+k-2p}{n-p}

观察一下,发现上面加起来是常数,下面加起来也是常数。把这个看作要求

i=1r(ik)(nimk).\sum_{i=1}^r \binom{i}{k} \binom{n-i}{m-k}.

先考虑 i=0n(ik)(nimk)\sum_{i=0}^n \binom{i}{k}\binom{n-i}{m-k}。若考虑 np+1n \to p+1,则 m,nm,n 不会修改,kkO(1)O(1) 的变化,于是式子可以 O(1)O(1) 维护。

增大了,显然只需要加上一项。

  • 增大 kk 的话,考虑这个式子的组合含义是在 nn 个白球中染黑 mm 个,且第 kk 个黑球的位置 r\leq r。 若 kk+1k \to k+1,限制变成第 k+1k+1 个黑球的位置 r\leq r,需要减少第 k+1k+1 个黑球位置 >r>r 的情况。

于是这部分也能做到 O(n)O(n)

T3-运输规划(xor)

题面

在数轴上依次排列着 nn 个工厂,从左到右第 ii 个工厂有 aia_i 单位货物。

商人蛋蛋拥有 2m2^m 种货车,编号为 0,1,,2m10,1,\cdots,2^m-1。若使用编号为 jj 的货车运输 xx 单位货物,则能获得的收益为:xjx\oplus j

其中 \oplus 表示按位异或,mm 为给定常数。

现在有 qq 次独立的运输计划,对于第 tt 次计划,蛋蛋只知道货车会前往某个工厂,工厂编号在区间 [l,r][l,r] 之间(包含两端)。在计划开始前,蛋蛋可以从所有货车中任选一种。

蛋蛋想知道:在最优选择下,每次运输在最坏情况下会获得多少收益。

1n105,1m50,1q5×105,0ai2m,1lrn1\leq n\leq10^5,1\leq m\leq50,1\leq q\leq5\times10^5,0\leq a_i\leq2^m,1\leq l\leq r\leq n

题解

肯定不能枚举端点。考虑在 trie 树上干点什么东西。令 fpf_p 为 trie 树上节点 pp 的答案,deppdep_p 为其深度,则:

f_p = \begin{cases} \max(f_{ls}, f_{rs}) & (ls \wedge rs) \$$6pt] f_{son} + 2^{m-dep_p} & \text{otherwise} \end{cases}

答案就是根节点的 dp 值。

枚举左端点,移动右端点,加入一个点只会修改 mm 个位置的 dp 值,O(n2m+q)O(n^2 m + q)

再进一步,直接莫队,O(nmq)O(nm \sqrt{q})

nn 相比 qq 很小,考虑从 nn 下功夫,即每个位置对答案的贡献。

换一种方法描述上面的 dp:选择一个值,从 trie 树上代表这个值的节点一直往上跳,没有兄弟就把和加上 2k2^k,求最⼤邻和。

显然这个值只会存在于区间内,因为空节点的 dp 值一定为 00

对于 ii 的深度为 jj 的祖先的兄弟,设这个兄弟子树内点的集合为 SS,则区间需要包含 ii 而不包含 SS 内任意的数,ii 对这个区间的贡献的第一个 mkm-k 位才是 1。显然我们只需要知道 SS 里的前驱与后继 (s,t)(s,t),区间的范围为 s<lir<ts<l \leq i \leq r < t

因为只有两个祖先,所以只有两个对 (s,t)(s,t),所以对于一个 ii,把所有区间分成了 m2m^2 种不同的贡献(左边 mm 种,右边 mm 种)。一个相同形式区间记作 [x1,x2],r=[y1,y2][x_1,x_2], r=[y_1,y_2]。这个限制并不好做,因为涉及到 l,rl,r。但是不难证明直接按 x1<lr<y2x_1<l \leq r < y_2 做是对的。因为缩小区间会使实际答案变⼩,而不会变⼤,一定不优。

于是直接扫描线,O(nm2logn+qlogn)O(nm^2 \log n + q \log n)

最后考虑用分块平衡,做到 O(nm2+qn)O(nm^2+q\sqrt{n})。搞笨的,直接树状数组差不多能直接过(官方数据并没有卡,感觉也难卡,所以干脆放了)。

其实要慢代码慢的地方是 nm2nm^2 的双 vector 遍历。

T4-不吼不叫(string)

题面

小 A 有一个初始字符串 tt。他希望通过一系列操作将 tt 转换为目标字符串 ss。每次操作,他可以选择切掉 tt 的一个前缀或一个后缀,但必须满足以下条件:切掉的前缀或后缀必须是操作后剩余字符串的子串。也就是说,如果切掉前缀 pp 后剩余字符串为 tt',那么 pp 必须是 tt' 的一个连续子串;同样,如果切掉后缀 sufsuf 后剩余字符串为 tt',那么 sufsuf 必须是 tt' 的一个连续子串。

小 A 想知道最少需要多少次操作才能从 tt 得到 ss。如果无法通过任何操作序列得到 ss,则输出 1-1

1st5×1031\leq|s|\leq|t|\leq5\times10^3,字符集 [a,z]\in[\text{a},\text{z}]

题解

正难则反,将切除操作改为添加,很显然尽可能大地添加字符段最优。

所以维护 fi,jf_{i,j} 表示以 i,ji,j 为右端点的最长公共后缀,同理维护 gi,jg_{i,j} 表示以 i,ji,j 为左端点的最长公共前缀。

同时,维护 li,j/ri,jl_{i,j}/r_{i,j} 表示区间 [l,r][l,r] 能向左/向右添加的最长段落长度。

sstt 中的子串位置开始,做一个类似多元最短路的操作即可。

复杂度 O(n2)O(n^2)